﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using xxpl1.HTTP;

namespace xxpl1.Utils
{
    public class Guard
    {
        private static readonly Regex cacheRegex = new Regex("max-age=(\\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static readonly Dictionary<string, bool> h2HHeaders = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
                                                              {
                                                                 { "connection",false},
                                                                 {  "keep-alive",false},
                                                                 {  "proxy-authenticate",false},
                                                                 {  "proxy-authorization",false},
                                                                 {  "proxy-connection",false},
                                                                 {  "te",false},
                                                                 {  "trailers",false},
                                                                 {  "transfer-encoding",false},
                                                                 {  "upgrade",false},
                                                                 {  "content-length",false},
                                                                 {  "Accept-Encoding",false},
                                                                 {  "User-Agent",false},
                                                              };

        private static readonly Dictionary<string, bool> forbidHeaders = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase) { { "if-range", false } };

        public static bool IsSafeHeader(string header)
        {
            if (string.IsNullOrEmpty(header))
            {
                return false;
            }
            if (h2HHeaders.ContainsKey(header))
            {
                return false;
            }
            if (forbidHeaders.ContainsKey(header))
            {
                return false;
            }

            return true;
        }

        public static bool IsAllowedMethod(string methodName)
        {
            if (string.IsNullOrEmpty(methodName))
            {
                return false;
            }

            string method = methodName.ToUpper();

            return method == "GET" || method == "HEAD" || method == "POST";
        }

        public static bool IsAllowedProtocol(string methodName)
        {
            if (string.IsNullOrEmpty(methodName))
            {
                return false;
            }

            string method = methodName.ToUpper();

            return method == "HTTP" || method == "HTTPS";
        }

        public static DateTime? ParseCacheControl(string httpHeader)
        {
            Match m = cacheRegex.Match(httpHeader);

            DateTime? result = null;

            if (m.Success)
            {
                int age;

                if (int.TryParse(m.Groups[1].Value, out age))
                {
                    result = DateTime.UtcNow.AddSeconds(age);
                }
            }

            return result;
        }
    }
}